import os
import random
import shutil

from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.io.VideoFileClip import VideoFileClip

import pyJianYingDraft as draft
from combinations.conf import logger
from pyJianYingDraft import Export_resolution, Export_framerate
from combinations.config import OUTPUT_PATH, COMBO_NAME_PREFIX, DRAFT_PATH
import pandas as pd


# 读取 Markdown 文
def read_excel_table(file_path):
    try:
        # 使用 pandas 读取 Excel 文件
        df = pd.read_excel(file_path)

        # 去除列名和数据的空格
        df = df.apply(lambda x: x.str.strip() if x.dtype == "object" else x)

        # 去除列名中的空格
        df.columns = df.columns.str.strip()
        return df

    except FileNotFoundError:
        logger.error(f"错误：文件 {file_path} 未找到。")
        return []
    except Exception as e:
        logger.error(f"解析 Excel 文件时出错：{e}")
        return []


import numpy as np


# 定义一个函数来生成帧时间偏移
def randomize_frame_timing(duration, fps_base=24, jitter_ratio=0.05):
    """
    在固定总时长内，为每一帧添加轻微随机时间偏移。

    Args:
        duration (float): 视频总时长（秒）
        fps_base (int): 基础帧率
        jitter_ratio (float): 抖动比例（建议 0~0.1）

    Returns:
        list: 每帧对应的时间戳列表
    """
    total_frames = int(duration * fps_base)
    base_interval = 1.0 / fps_base
    times = []

    current_time = 0.0
    for _ in range(total_frames):
        interval_jitter = base_interval * (1 + np.random.uniform(-jitter_ratio, jitter_ratio))
        times.append(current_time)
        current_time += interval_jitter

    # 最后缩放时间轴，保证总长度与原视频一致
    scale_factor = duration / current_time
    times = [t * scale_factor for t in times]
    return times



def export_drafts(combo_name,zi_mu=False, kou_tu=False,audio_path="",enable_delete=False,frame_sampling=False):
    # df = read_excel_table(markdown_file_path)
    # 提取“组合名称”列
    name = combo_name

    # logger.error(f"正在导出草稿：{draft_names}")
    ctrl = draft.Jianying_controller()
    export_folder = os.path.join(OUTPUT_PATH, COMBO_NAME_PREFIX)
    os.makedirs(export_folder, exist_ok=True)

    logger.info(f"正在导出视频：{name}")
    try:
        output_path = str(os.path.join(str(export_folder), f"{name}.mp4"))
        ctrl.export_draft(name, output_path, resolution=Export_resolution.RES_1080P,
                          framerate=Export_framerate.FR_24, zi_mu=zi_mu, kou_tu=kou_tu)

        # 每过 10 个删除一次文件夹
        # if (i+1) % 10 == 0:
            # 计算当前批次的起始和结束索引
        # start_index = i - 9  # 当前批次的第一个 k 值
        # end_index = i  # 当前批次的最后一个 k 值
        #
        # # 删除当前批次的文件夹
        # for i in range(start_index, end_index + 1):
        if enable_delete:
            folder_path = os.path.join(DRAFT_PATH, name)
            if os.path.exists(folder_path):
                shutil.rmtree(folder_path)
                logger.info(f"已删除文件夹: {folder_path}")
            else:
                logger.warning(f"文件夹不存在: {folder_path}")

        if audio_path != "":
            # 如果 需要视频剪裁，需要提供音频的文件路径
            logger.info(f"匹配到音频文件路径：{audio_path}，开始依据合成视频所用的音频进行裁剪视频。")

            # 读取音频时长
            audio_clip = AudioFileClip(audio_path)
            audio_duration = audio_clip.duration
            audio_clip.close()

            # 读取视频文件
            video_clip = VideoFileClip(output_path)
            # 根据音频时长裁剪视频
            # audio_speed = 1.1
            # accelerated_audio_duration = audio_duration / audio_speed
            accelerated_audio_duration = audio_duration + 1
            if video_clip.duration > accelerated_audio_duration:
                video_clip = video_clip.subclipped(0, accelerated_audio_duration)
                # 保存裁剪后的视频
                new_output_path = os.path.join(str(export_folder), '已剪辑', f"剪裁_{name}.mp4")
                os.makedirs(os.path.join(str(export_folder), '已剪辑'), exist_ok=True)
                video_clip.write_videofile(new_output_path, codec="libx264")
                logger.info(f"视频剪辑成功，保存路径为：{new_output_path}")

                output_path = new_output_path

            video_clip.close()

        if frame_sampling:

            """
            原视频 24fps，共 240 帧，时长 10s；
            经过处理后仍为 10s；
            但每帧显示时间略有差异（如第1帧 0.04s，第2帧 0.042s...）；
            播放无感，但底层帧结构发生变化。
            
            法对视频帧进行“时间轴扰动”，你可以控制每一帧的时间点，在不改变内容的前提下做帧率微调。
            """
            logger.info(f"开始进行视频帧“时间轴扰动”处理：{name}")

            video_clip = VideoFileClip(output_path)

            # 随机化帧时间轴
            duration = video_clip.duration
            times = randomize_frame_timing(duration, fps_base=24, jitter_ratio=0.05)  # 抖动 ±5%

            # 自定义 transform 函数
            def custom_transform(get_frame, t, times_list, total_frames, duration):
                """
                自定义帧映射函数，用于替代原来的 .fl() 逻辑
                """
                # 计算当前 t 应该对应哪个帧索引
                frame_index = min(int(round(t * total_frames / duration)), len(times_list) - 1)
                actual_time = times_list[frame_index]
                return get_frame(actual_time)

            # 构造带参数的 transform 函数
            def make_frame_func(times_list, total_frames, duration):
                def func(get_frame, t):
                    return custom_transform(get_frame, t, times_list, total_frames, duration)

                return func

            # 应用 transform
            total_frames = int(duration * 24)  # 根据原始帧率计算总帧数
            new_clip = video_clip.transform(make_frame_func(times, total_frames, duration))

            # 导出视频
            new_output_path = os.path.join(str(export_folder), '动态帧扰乱', f"帧扰乱_{combo_name}.mp4")
            os.makedirs(os.path.dirname(new_output_path), exist_ok=True)
            new_clip.write_videofile(new_output_path, codec="libx264", audio_codec="aac", fps=24)

    except Exception as e:
        logger.error(f"导出视频出错：{e} *******************{name}")
        raise Exception(f"导出视频出错：{e} *******************{name}")
